Content Display Macros
**Referenced Files in This Document** - [case-study-card.njk](file://src/_includes/macros/case-study-card.njk) - [news-article-card.njk](file://src/_includes/macros/news-article-card.njk) - [testimonial-card.njk](file://src/_includes/macros/testimonial-card.njk) - [team-flip-card.njk](file://src/_includes/macros/team-flip-card.njk) - [service-capability-card.njk](file://src/_includes/macros/service-capability-card.njk) - [capabilities.json](file://src/_data/capabilities.json) - [testimonials.json](file://src/_data/testimonials.json) - [adelaide-city-fc.md](file://src/content/cases/adelaide-city-fc.md) - [2025-10-17-political-powerhouse.md](file://src/content/news/2025-10-17-political-powerhouse.md) - [01-matt-neagle.md](file://src/content/team/01-matt-neagle.md) - [21-cases-page.css](file://src/assets/css/modules/21-cases-page.css) - [22-news-insights-page.css](file://src/assets/css/modules/22-news-insights-page.css) - [client-marquee.njk](file://src/_includes/macros/client-marquee.njk)Table of Contents
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
Introduction
This document explains the content display macros used across the site to render portfolio case studies, news articles, testimonials, team profiles, and service capabilities. It covers each macro’s parameters, conditional rendering, image handling with lazy loading, content sanitization, and how they integrate with Eleventy data collections. It also documents styling classes, responsive behavior, and accessibility features for each component.
Project Structure
The macros live under the Eleventy includes directory and are consumed by pages and collections. Styles for each component are defined in dedicated CSS modules. Example Markdown content demonstrates how front matter and content fields are passed into the macros.
graph TB
subgraph "Eleventy Includes"
M1["case-study-card.njk"]
M2["news-article-card.njk"]
M3["testimonial-card.njk"]
M4["team-flip-card.njk"]
M5["service-capability-card.njk"]
end
subgraph "Data"
D1["capabilities.json"]
D2["testimonials.json"]
end
subgraph "Content"
C1["content/cases/*.md"]
C2["content/news/*.md"]
C3["content/team/*.md"]
end
subgraph "Styles"
S1["21-cases-page.css"]
S2["22-news-insights-page.css"]
end
C1 --> M1
C2 --> M2
C3 --> M4
D1 --> M5
D2 --> M3
M1 --> S1
M2 --> S2
Diagram sources
- [case-study-card.njk:1-20](file://src/_includes/macros/case-study-card.njk#L1-L20)
- [news-article-card.njk:1-35](file://src/_includes/macros/news-article-card.njk#L1-L35)
- [testimonial-card.njk:1-18](file://src/_includes/macros/testimonial-card.njk#L1-L18)
- [team-flip-card.njk:1-18](file://src/_includes/macros/team-flip-card.njk#L1-L18)
- [service-capability-card.njk:1-11](file://src/_includes/macros/service-capability-card.njk#L1-L11)
- [capabilities.json:1-53](file://src/_data/capabilities.json#L1-L53)
- [testimonials.json:1-24](file://src/_data/testimonials.json#L1-L24)
- [21-cases-page.css:1-55](file://src/assets/css/modules/21-cases-page.css#L1-L55)
- [22-news-insights-page.css:1-151](file://src/assets/css/modules/22-news-insights-page.css#L1-L151)
Section sources
- [case-study-card.njk:1-20](file://src/_includes/macros/case-study-card.njk#L1-L20)
- [news-article-card.njk:1-35](file://src/_includes/macros/news-article-card.njk#L1-L35)
- [testimonial-card.njk:1-18](file://src/_includes/macros/testimonial-card.njk#L1-L18)
- [team-flip-card.njk:1-18](file://src/_includes/macros/team-flip-card.njk#L1-L18)
- [service-capability-card.njk:1-11](file://src/_includes/macros/service-capability-card.njk#L1-L11)
- [capabilities.json:1-53](file://src/_data/capabilities.json#L1-L53)
- [testimonials.json:1-24](file://src/_data/testimonials.json#L1-L24)
- [21-cases-page.css:1-55](file://src/assets/css/modules/21-cases-page.css#L1-L55)
- [22-news-insights-page.css:1-151](file://src/assets/css/modules/22-news-insights-page.css#L1-L151)
Core Components
- Case Study Card: Renders a portfolio case study with image, category, client, title, body, and optional quote box.
- News Article Card: Renders news items with headline, excerpt, date, and metadata; supports two variants (carousel vs. expanded).
- Testimonial Card: Renders a testimonial quote with author and role; supports case-study-specific styling.
- Team Flip Card: Renders an interactive team member profile with front/back faces and a flip interaction.
- Service Capability Card: Renders a service offering with capability image, title, description, and a learn-more link.
Each macro accepts structured data from Eleventy collections and front matter, applies conditional rendering, and outputs semantic HTML with accessibility attributes.
Section sources
- [case-study-card.njk:1-20](file://src/_includes/macros/case-study-card.njk#L1-L20)
- [news-article-card.njk:1-35](file://src/_includes/macros/news-article-card.njk#L1-L35)
- [testimonial-card.njk:1-18](file://src/_includes/macros/testimonial-card.njk#L1-L18)
- [team-flip-card.njk:1-18](file://src/_includes/macros/team-flip-card.njk#L1-L18)
- [service-capability-card.njk:1-11](file://src/_includes/macros/service-capability-card.njk#L1-L11)
Architecture Overview
The macros are invoked from templates and Nunjucks loops over Eleventy collections. They rely on front matter fields and content bodies, apply filters (such as date formatting), sanitize content where appropriate, and render HTML with consistent classes for styling.
sequenceDiagram
participant Page as "Page Template"
participant Coll as "Eleventy Collection"
participant Macro as "Macro (Nunjucks)"
participant DOM as "Rendered HTML"
Page->>Coll : "Loop over collection"
Coll-->>Page : "item"
Page->>Macro : "card(item)"
Macro->>Macro : "Conditional rendering"
Macro->>DOM : "HTML with classes and attributes"
DOM-->>Page : "Rendered card"
[No sources needed since this diagram shows conceptual workflow, not actual code structure]
Detailed Component Analysis
Case Study Card
- Purpose: Display a single case study with media, metadata, body content, and optional quote.
- Parameters:
- item: Object containing front matter fields and content body.
- Fields used:
- item.data.image, item.data.image_alt
- item.data.category, item.data.client, item.data.title
- item.content (sanitized via safe filter)
- item.data.quote, item.data.quote_author (optional)
- Conditional rendering:
- Quote box renders only when quote exists.
- Accessibility:
- Image alt text from image_alt.
- Semantic headings for category, client, title.
- Styling and responsiveness:
- Uses case-study-card and nested classes for layout and hover effects.
- Grid-based page layout for multiple cards.
- Practical usage:
- Loop over the cases collection and pass each item to the macro.
flowchart TD
Start(["Render Case Study"]) --> Img["Render image with alt and lazy loading"]
Img --> Meta["Render category, client, title"]
Meta --> Body["Render sanitized content body"]
Body --> HasQuote{"Has quote?"}
HasQuote --> |Yes| QuoteBox["Render quote box with author"]
HasQuote --> |No| End(["Done"])
QuoteBox --> End
Diagram sources
- [case-study-card.njk:1-20](file://src/_includes/macros/case-study-card.njk#L1-L20)
Section sources
- [case-study-card.njk:1-20](file://src/_includes/macros/case-study-card.njk#L1-L20)
- [adelaide-city-fc.md:1-14](file://src/content/cases/adelaide-city-fc.md#L1-L14)
- [21-cases-page.css:21-52](file://src/assets/css/modules/21-cases-page.css#L21-L52)
News Article Card
- Purpose: Display news items in two forms: compact carousel cards or expanded article cards with optional full content and PDF link.
- Parameters:
- item: News item with front matter and content.
- variant: String defaulting to carousel; when not carousel, renders expanded form.
- Fields used:
- item.data.date (formatted via dateFormat filter)
- item.data.title, item.data.excerpt
- item.data.image, item.data.image_alt (optional)
- item.content (optional; expands into details/summary)
- item.data.pdf_url, item.data.pdf_label (optional)
- Conditional rendering:
- Expanded details block appears only when content exists.
- Image renders only when present.
- Accessibility:
- Read more link includes aria-label with title.
- Details/summary toggles with keyboard-friendly semantics.
- Styling and responsiveness:
- Carousel variant uses text-only card with category-like metadata.
- Expanded variant uses a grid and hover effects; includes animated details expansion.
- Practical usage:
- Pass the news collection to the macro with variant selection per layout.
flowchart TD
Start(["Render News Card"]) --> Variant{"Variant == 'carousel'?"}
Variant --> |Yes| Compact["Render date, title, excerpt, read link"]
Variant --> |No| Expanded["Render image (optional), date, title, excerpt"]
Expanded --> HasContent{"Has content?"}
HasContent --> |Yes| Details["Render details/summary with expanded content"]
HasContent --> |No| End(["Done"])
Details --> PDF{"Has pdf_url?"}
PDF --> |Yes| PDFLink["Render PDF link with label"]
PDF --> |No| End
PDFLink --> End
Diagram sources
- [news-article-card.njk:1-35](file://src/_includes/macros/news-article-card.njk#L1-L35)
Section sources
- [news-article-card.njk:1-35](file://src/_includes/macros/news-article-card.njk#L1-L35)
- [2025-10-17-political-powerhouse.md:1-18](file://src/content/news/2025-10-17-political-powerhouse.md#L1-L18)
- [22-news-insights-page.css:98-137](file://src/assets/css/modules/22-news-insights-page.css#L98-L137)
Testimonial Card
- Purpose: Render a testimonial quote with author and role; supports a case-study variant.
- Parameters:
- quote: Testimonial text.
- author: Author name.
- role: Author role.
- isCaseStudy: Boolean flag to switch to case-study quote box styling.
- Conditional rendering:
- Switches between testimonial-card and case-quote-box depending on flag.
- Accessibility:
- Semantic blockquote and cite elements.
- Styling and responsiveness:
- Uses testimonial-card and case-quote-box classes; responsive typography and spacing.
- Practical usage:
- Loop over testimonials collection or pass individual testimonials to the macro.
flowchart TD
Start(["Render Testimonial"]) --> IsCS{"isCaseStudy?"}
IsCS --> |Yes| CaseBox["Render case-quote-box with quote and author"]
IsCS --> |No| NormalCard["Render testimonial-card with quote, author, role"]
CaseBox --> End(["Done"])
NormalCard --> End
Diagram sources
- [testimonial-card.njk:1-18](file://src/_includes/macros/testimonial-card.njk#L1-L18)
Section sources
- [testimonial-card.njk:1-18](file://src/_includes/macros/testimonial-card.njk#L1-L18)
- [testimonials.json:1-24](file://src/_data/testimonials.json#L1-L24)
Team Flip Card
- Purpose: Interactive team member profile with front face (image and overlay) and back face (short bio and link).
- Parameters:
- item: Team member with front/back data.
- Fields used:
- item.data.image_index, item.data.image_alt_index
- item.data.name, item.data.role
- item.data.bio_short
- item.data.anchor (used in internal anchor link)
- Accessibility:
- Image alt text from image_alt_index.
- Read more link includes aria-label with name.
- Styling and responsiveness:
- Uses team-card and team-card-inner with front/back faces; hover and flip interactions handled by CSS.
- Practical usage:
- Loop over the team collection and pass each item to the macro.
flowchart TD
Start(["Render Team Card"]) --> Front["Render front: image + overlay name/role"]
Front --> Back["Render back: short bio + read more link"]
Back --> End(["Done"])
Diagram sources
- [team-flip-card.njk:1-18](file://src/_includes/macros/team-flip-card.njk#L1-L18)
Section sources
- [team-flip-card.njk:1-18](file://src/_includes/macros/team-flip-card.njk#L1-L18)
- [01-matt-neagle.md:1-21](file://src/content/team/01-matt-neagle.md#L1-L21)
Service Capability Card
- Purpose: Display a service offering with image, title, description, and a learn-more link.
- Parameters:
- service: Object representing a service capability.
- Fields used:
- service.image, service.image_alt
- service.title, service.body
- service.url
- service.card_class (optional; defaults to card-wide)
- Accessibility:
- Learn more link includes aria-label with title.
- Styling and responsiveness:
- Uses service-bg-card with variant classes (card-wide, card-square, card-narrow) and nested content layout.
- Practical usage:
- Loop over capabilities data and pass each service to the macro.
flowchart TD
Start(["Render Service Card"]) --> Img["Render image with alt and lazy loading"]
Img --> Layout["Apply card class (default wide)"]
Layout --> Content["Render title, body, learn more link"]
Content --> End(["Done"])
Diagram sources
- [service-capability-card.njk:1-11](file://src/_includes/macros/service-capability-card.njk#L1-L11)
Section sources
- [service-capability-card.njk:1-11](file://src/_includes/macros/service-capability-card.njk#L1-L11)
- [capabilities.json:1-53](file://src/_data/capabilities.json#L1-L53)
Dependency Analysis
- Data-to-Macro Contracts:
- Case Study Card expects item.data.image, item.data.image_alt, item.data.category, item.data.client, item.data.title, item.content, and optionally item.data.quote and item.data.quote_author.
- News Article Card expects item.data.date, item.data.title, item.data.excerpt, and optionally item.data.image, item.data.image_alt, item.content, item.data.pdf_url, item.data.pdf_label.
- Testimonial Card expects quote, author, role, and optional isCaseStudy flag.
- Team Flip Card expects item.data.image_index, item.data.image_alt_index, item.data.name, item.data.role, item.data.bio_short, item.data.anchor.
- Service Capability Card expects service.image, service.image_alt, service.title, service.body, service.url, and optional service.card_class.
- Rendering Variants:
- News Article Card supports a variant parameter to switch between carousel and expanded forms.
- Filters and Sanitization:
- Macros use a safe filter for content fields that contain HTML.
- Date formatting is applied via a dateFormat filter on item.data.date.
- Styling Cohesion:
- Each macro targets specific CSS classes defined in dedicated style modules, ensuring consistent layout and responsive behavior.
graph LR
CS["case-study-card.njk"] --> CSS1["21-cases-page.css"]
NA["news-article-card.njk"] --> CSS2["22-news-insights-page.css"]
TC["testimonial-card.njk"] --> CSS1
TF["team-flip-card.njk"] --> CSS1
SC["service-capability-card.njk"] --> CSS1
CS --> Cases["content/cases/*.md"]
NA --> News["content/news/*.md"]
TF --> Team["content/team/*.md"]
SC --> Caps["capabilities.json"]
TC --> Testi["testimonials.json"]
Diagram sources
- [case-study-card.njk:1-20](file://src/_includes/macros/case-study-card.njk#L1-L20)
- [news-article-card.njk:1-35](file://src/_includes/macros/news-article-card.njk#L1-L35)
- [testimonial-card.njk:1-18](file://src/_includes/macros/testimonial-card.njk#L1-L18)
- [team-flip-card.njk:1-18](file://src/_includes/macros/team-flip-card.njk#L1-L18)
- [service-capability-card.njk:1-11](file://src/_includes/macros/service-capability-card.njk#L1-L11)
- [21-cases-page.css:1-55](file://src/assets/css/modules/21-cases-page.css#L1-L55)
- [22-news-insights-page.css:1-151](file://src/assets/css/modules/22-news-insights-page.css#L1-L151)
- [capabilities.json:1-53](file://src/_data/capabilities.json#L1-L53)
- [testimonials.json:1-24](file://src/_data/testimonials.json#L1-L24)
- [adelaide-city-fc.md:1-14](file://src/content/cases/adelaide-city-fc.md#L1-L14)
- [2025-10-17-political-powerhouse.md:1-18](file://src/content/news/2025-10-17-political-powerhouse.md#L1-L18)
- [01-matt-neagle.md:1-21](file://src/content/team/01-matt-neagle.md#L1-L21)
Section sources
- [capabilities.json:1-53](file://src/_data/capabilities.json#L1-L53)
- [testimonials.json:1-24](file://src/_data/testimonials.json#L1-L24)
- [adelaide-city-fc.md:1-14](file://src/content/cases/adelaide-city-fc.md#L1-L14)
- [2025-10-17-political-powerhouse.md:1-18](file://src/content/news/2025-10-17-political-powerhouse.md#L1-L18)
- [01-matt-neagle.md:1-21](file://src/content/team/01-matt-neagle.md#L1-L21)
Performance Considerations
- Lazy Loading: All macros that render images use the loading="lazy" attribute to defer offscreen image loading, improving initial page performance.
- Minimal JavaScript: The team flip card relies on CSS transforms and transitions; avoid heavy client-side scripts.
- Content Sanitization: The safe filter is used for content fields that may include HTML; ensure only trusted content is stored in item.content and testimonials to prevent XSS.
- Responsive Images: Prefer modern formats and sizes; the CSS uses object-fit for consistent aspect ratios.
[No sources needed since this section provides general guidance]
Troubleshooting Guide
- Missing Alt Text:
- Symptom: Accessibility warnings for images.
- Fix: Ensure image_alt fields are populated in front matter.
- Empty Content Body:
- Symptom: Case study body missing.
- Fix: Verify item.content is present in the Markdown file.
- Missing Quote Data:
- Symptom: Quote box not appearing.
- Fix: Confirm quote and quote_author are set in front matter.
- Expanded News Content Not Showing:
- Symptom: No “Read full release” toggle.
- Fix: Add content to the Markdown file; ensure dateFormat filter is available.
- PDF Link Missing:
- Symptom: No download link in expanded news.
- Fix: Set pdf_url and optionally pdf_label in front matter.
- Team Anchor Links:
- Symptom: “Read more” link does not jump to profile.
- Fix: Ensure anchor field matches the target element ID.
- Service Card Layout:
- Symptom: Unexpected card width.
- Fix: Set card_class to card-wide, card-square, or card-narrow as desired.
Section sources
- [case-study-card.njk:1-20](file://src/_includes/macros/case-study-card.njk#L1-L20)
- [news-article-card.njk:1-35](file://src/_includes/macros/news-article-card.njk#L1-L35)
- [testimonial-card.njk:1-18](file://src/_includes/macros/testimonial-card.njk#L1-L18)
- [team-flip-card.njk:1-18](file://src/_includes/macros/team-flip-card.njk#L1-L18)
- [service-capability-card.njk:1-11](file://src/_includes/macros/service-capability-card.njk#L1-L11)
Conclusion
These macros provide a consistent, accessible, and performant way to render diverse content types across the site. By adhering to the documented parameter contracts, conditional rendering logic, and styling classes, content teams can reliably compose pages and collections while maintaining responsive and inclusive user experiences.
[No sources needed since this section summarizes without analyzing specific files]
Appendices
Parameter Reference Tables
-
Case Study Card
- item.data.image: string
- item.data.image_alt: string
- item.data.category: string
- item.data.client: string
- item.data.title: string
- item.content: string (HTML)
- item.data.quote: string (optional)
- item.data.quote_author: string (optional)
-
News Article Card
- item.data.date: date
- item.data.title: string
- item.data.excerpt: string
- item.data.image: string (optional)
- item.data.image_alt: string (optional)
- item.content: string (HTML, optional)
- item.data.pdf_url: string (optional)
- item.data.pdf_label: string (optional)
- variant: string (default "carousel")
-
Testimonial Card
- quote: string
- author: string
- role: string
- isCaseStudy: boolean (default false)
-
Team Flip Card
- item.data.image_index: string
- item.data.image_alt_index: string
- item.data.name: string
- item.data.role: string
- item.data.bio_short: string
- item.data.anchor: string
-
Service Capability Card
- service.image: string
- service.image_alt: string
- service.title: string
- service.body: string
- service.url: string
- service.card_class: string (optional)
Section sources
- [case-study-card.njk:1-20](file://src/_includes/macros/case-study-card.njk#L1-L20)
- [news-article-card.njk:1-35](file://src/_includes/macros/news-article-card.njk#L1-L35)
- [testimonial-card.njk:1-18](file://src/_includes/macros/testimonial-card.njk#L1-L18)
- [team-flip-card.njk:1-18](file://src/_includes/macros/team-flip-card.njk#L1-L18)
- [service-capability-card.njk:1-11](file://src/_includes/macros/service-capability-card.njk#L1-L11)
Practical Usage Examples
- Case Studies:
- Loop over the cases collection and pass each item to the case study card macro.
- Example path: [adelaide-city-fc.md:1-14](file://src/content/cases/adelaide-city-fc.md#L1-L14)
- News Articles:
- Loop over the news collection; choose variant "carousel" for carousels or default for expanded cards.
- Example path: [2025-10-17-political-powerhouse.md:1-18](file://src/content/news/2025-10-17-political-powerhouse.md#L1-L18)
- Testimonials:
- Loop over testimonials data or pass individual testimonials to the macro.
- Example path: [testimonials.json:1-24](file://src/_data/testimonials.json#L1-L24)
- Team Profiles:
- Loop over the team collection and pass each item to the team flip card macro.
- Example path: [01-matt-neagle.md:1-21](file://src/content/team/01-matt-neagle.md#L1-L21)
- Services:
- Loop over capabilities data and pass each service to the service capability card macro.
- Example path: [capabilities.json:1-53](file://src/_data/capabilities.json#L1-L53)
Section sources
- [adelaide-city-fc.md:1-14](file://src/content/cases/adelaide-city-fc.md#L1-L14)
- [2025-10-17-political-powerhouse.md:1-18](file://src/content/news/2025-10-17-political-powerhouse.md#L1-L18)
- [testimonials.json:1-24](file://src/_data/testimonials.json#L1-L24)
- [01-matt-neagle.md:1-21](file://src/content/team/01-matt-neagle.md#L1-L21)
- [capabilities.json:1-53](file://src/_data/capabilities.json#L1-L53)
Related Utilities
- Client Marquee Macro (for reference on lazy loading and accessibility):
- Demonstrates consistent alt text and lazy loading patterns.
- Example path: [client-marquee.njk:1-27](file://src/_includes/macros/client-marquee.njk#L1-L27)
Section sources
- [client-marquee.njk:1-27](file://src/_includes/macros/client-marquee.njk#L1-L27)